JS中的跨域是受到限制的,但是跨域有时候又是必须的,藉此,各种高手牛人想尽办法使得JS能够跨域获取数据,有的方法真的很巧妙
在此记录一下常用的三种跨域方法,如下:
一、不同子域名之间的(a.example.com|b.example.com)的跨域访问。
这种跨域调用比较常见,比如a.example.com 下的 a.htm 页面,需要调用 b.example.com 下的 b.htm页面里面的getData函数, 首先需要在a.htm页面中用iframe 框架把b.htm页面引用进来
然后同时在a.htm页面与b.htm页面中设置:document.domain = "example.com"; 这样a.htm就可以获取b.htm中的window documet 然后来获取b.htm中的数据getData了,获取b.htm中的document方法为:
function getIframeDocument(id){ returen document.getElementById(id).contentDocument || document.getElementById(id).document;}
二、不同域名之间的hash传递参数(www.a.com | www.b.com)
常见的一个例子就是iframe自动适应大小,a域名下的a.htm 框架(iframe)了b域名中的b.htm,而b.htm的大小是不固定的,这时候就需要通过跨域传递b.htm的宽度与高度到a.htm中。
这个参数是怎么传递的呢?是通过hash来传递的(www.b.com/b.htm#width|height)其中#号后面的参数width|height 即为window.location.hash的值
而改变hash的值也不会造成页面的跳转,但是这样还是跨域的,所以需要在a域下增加一个c.htm中间页面,这样c.htm与a.htm之间就是相同的域下,可以传递数
据,把c.htm页面通过iframe到b.htm中,由b.htm控制,看下图: 现在的关系为,a.htm中iframe加入了b.htm,b.htm页面中iframe加入了c.htm
a.htm代码如下:
Demo 这是A域a
b.htm代码如下:
c.htm代码如下:
这样就可以通过hash来传递数据,缺点是只支持string类型,大小受到限制!
三、通过jsonp来实现不通域名之间跨域传递数据。
什么是jsonp(JSONP即JSON with Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求,我们可以通过使用 html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递对象。这种跨域的通讯方式称为JSONP。)
通俗来讲就是通过<script type="text/javascript" src="调用生成JS文件的地址并传递回调参数"></script> 来调用要执行的代码。
也可以通过createElement('script')来生成,如下:
var JSONP = document.createElement("script") ;//然后设置其src属性
因为JS文件无论在什么地方都可以调用并执行,比如各种统计JS等,回调参数是怎么回事呢,就是告诉要传递数据的页面给把数据通过这个函数传递给我,大家
大家可以试一下下面这个地址:
http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?
上面的地址是flicker的API,其中的jsoncallback=? 中的问号替换成你自定义的回调函数,然后对方就会通过这个回调函数给你传递数据:
比如随便起名一个回调函数vvgcallback:
http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=vvgcallback
然后对方生成的js就是这样的(可以把以上地址复制到地址栏测试):
vvgcallback({ "title": "Recent Uploads tagged cat", "link": "http://www.flickr.com/photos/tags/cat/", "description": "", "modified": "2012-08-15T06:07:40Z", "generator": "http://www.flickr.com/", "items": [ { "title": "A squirell about to jump", "link": "http://www.flickr.com/photos/64477042@N00/7786494040/", "media": {"m":"http://farm9.staticflickr.com/8422/7786494040_a7a506dfdc_m.jpg"}, "date_taken": "2012-08-10T15:19:40-08:00", "description": "Dr arun kapoor<\/a> posted a photo:<\/p>
就相当与在页面执行vvgcallback()函数,括号中间的就是传递的JSON数据。这样就想当于在你的页面里面执行了以上的代码。从而实现了跨域传递数据。